<?php
/*
 *---------------------------------------------------------------------------
 *
 *                  T E N C E N T   P R O P R I E T A R Y
 *
 *     COPYRIGHT (c)  2008 BY  TENCENT  CORPORATION.  ALL RIGHTS
 *     RESERVED.   NO  PART  OF THIS PROGRAM  OR  PUBLICATION  MAY
 *     BE  REPRODUCED,   TRANSMITTED,   TRANSCRIBED,   STORED  IN  A
 *     RETRIEVAL SYSTEM, OR TRANSLATED INTO ANY LANGUAGE OR COMPUTER
 *     LANGUAGE IN ANY FORM OR BY ANY MEANS, ELECTRONIC, MECHANICAL,
 *     MAGNETIC,  OPTICAL,  CHEMICAL, MANUAL, OR OTHERWISE,  WITHOUT
 *     THE PRIOR WRITTEN PERMISSION OF :
 *
 *                        TENCENT  CORPORATION
 *
 *       Advertising Platform R&D Team, Advertising Platform & Products
 *       Tencent Ltd.
 *---------------------------------------------------------------------------
 */

/**
 * The class for dispatcher request and send response
 
 */
class JYDispatcher {
    /**
     * @var string $controllerName   the controller name
     *
     * @access private
     */
    private $controllerName;

    /**
     * @var string $actionName    the action name
     *
     * @access private
     */
    private $actionName;

    /**
     * @var string    the layout name
     *
     * @access private
     */
    private $layout;

    /**
     * @var TMWebRequest $request
     */
    private $request;

    /**
     * @var TMWebResponse $response
     */
    private $response;


    private function __construct() {
    }

    /**
     * 用于存储类的单实例
     * @var JYDispatcher $instance 类的单实例。
     */
    private static $instance = null;

    /**
     * Creates a new static JYDispatcher instance.
     *
     * @param  array $parameters             additional request parameters array
     * @param  array $attributes             additional request attributes array
     * @param  array $options                additional request options array
     *
     * @return JYDispatcher                  An dispatcher instance
     */
    public static function createInstance($parameters = array(), $attributes = array(), $options = array()) {
        if(self::$instance == null) {
            $class = __CLASS__;
            self::$instance = new $class();

            self::$instance->initialize($parameters, $attributes, $options);
        }
        return self::$instance;
    }

    public static function getInstance($parameters = array(), $attributes = array(), $options = array()) {
        if(self::$instance == null) {
            $class = __CLASS__;
            self::$instance = new $class();

            self::$instance->initialize($parameters, $attributes, $options);
        }
        return self::$instance;
    }

    /**
     * Initializes the current sfContext instance.
     *
     * @param  array $parameters             additional request parameters array
     * @param  array $attributes             additional request attributes array
     * @param  array $options                additional request options array
     *
     * @return void
     */
    public function initialize($parameters = array(), $attributes = array(), $options = array()) {
        $this->request = new JYWebRequest($parameters, $attributes);
        $this->response = new JYWebResponse($options);
        $this->setController();
        $this->setAction();
    }

    /**
     * Dispatch the request
     * First: search controller
     * Second: execute controller->execute
     * Third: setContent
     * Forth: send response, send http header, send http body
     *
     * @return void
     */
    public function dispatch($key='') {
        // 执行controller的actionAction
        $controller = $this->getController();
        $action = $this->getAction();
        
        $cache = JYYaml::getInstance()->execute(PAGE_CACHE);
        $cache = $cache[$controller.'_'.$action];
		
        //判断缓存数据
        if($cache){
	        $key = '_dispatcher'.$key.'_'.$controller.'_'.$action
	            .print_r($this->request->getPostParameters(),true)
	            .print_r($this->request->getGetParameters(),true);
	    	$key = APP_SPACE.md5($key);		
			
			if(!$refresh){
				$content = JYMemcache::get($key);
				if($content){ 
					echo $content;
					exit();
				}
			}
        }

        // 确定Controller位置
        $controllerFileName = $controller. "Controller";
        $classPath = APP_PATH . 'controllers/' . $controllerFileName . '.php';
		
        // 运行controller或者component，生成内容
        $content = '';
        if (file_exists($classPath)) {
            require_once($classPath);
            $controllerInstance = new $controllerFileName($controller, $action);
            $funcName = $action."Action";            
             
            $content = $controllerInstance->execute($controllerInstance,$funcName);
        }else {
            header('HTTP/1.1 404 Page Not Found');
        }
        
        //缓存页面
        if($cache&&!JYMemcache::add($key,$content,$cache)){
			JYMemcache::set($key,$content,$cache);
		}	

        echo $content;
        exit();
    }

    /**
     * Set controller name from url
     *
     * @return void
     */
    private function setController() {
        $controller = empty($_GET['c']) ? APIConfig::defaultControllerName : $_GET['c'];
        $this->controllerName = strtolower ( $controller );
    }

    /**
     * Set controller name
     *
     * @access public
     * @param  string $name     the controller name
     * @return void
     */
    public function setControllerName($name) {
        $this->controllerName = $name;
    }

    /**
     * Set action name
     *
     * @access public
     * @param  string $name     the action name
     * @return void
     */
    public function setActionName($name) {
        $this->actionName = $name;
    }

    /**
     * Get controller name
     *
     * @return controllerName   The controller name
     */
    public function getController() {
        return empty($this->controllerName) ? APIConfig::defaultControllerName : $this->controllerName;
    }

    /**
     * Set action name from url
     *
     * @return void
     */
    private function setAction() {
        $action = empty($_GET[a]) ? APIConfig::defaultActionName : $_GET[a];
        $this->actionName = strtolower ( $action );
    }

    /**
     * Get controller name
     *
     * @return actionName   The action name
     */
    public function getAction() {
        return empty($this->actionName) ? APIConfig::defaultActionName : $this->actionName;
    }

    /**
     * Get response name
     *
     * @return TMWebResponse $response
     */
    public function getResponse() {
        return $this->response;
    }

    /**
     * Get request name
     *
     * @return TMWebRequest $request
     */
    public function getRequest() {
        return $this->request;
    }

    /**
     * 实现请求转发，对于用户来说不透明
     *
     * @param  string $controller      the forwarded controller name
     * @param  string $action          the forwarded action name
     * @return string $content         the content string
     */
    public function forward($controller, $action) {
        $this->setControllerName($controller);
        $this->setActionName($action);
        $this->dispatch();
        exit();
    }
}
